from requests import request
from common.query_set import RequestQuerySet
from django.db import models
from django.contrib.gis.db import models as gis_models
from django import forms

from apps.user.models import Firm

class BaseModel(models.Model):
    """模型抽象基类"""
    create_time = models.DateTimeField(auto_now_add=True, null=True, verbose_name='创建时间')
    update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    is_delete = models.BooleanField(default=False, verbose_name='删除标记')
    firm = models.ForeignKey(Firm, null=True, blank=True, on_delete=models.CASCADE, verbose_name='所属企业')

    class Meta:
        """说明是一个抽象基类"""
        abstract = True

class BaseModelNoFirm(models.Model):
    """模型抽象基类"""
    create_time = models.DateTimeField(auto_now_add=True, null=True, verbose_name='创建时间')
    update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    is_delete = models.BooleanField(default=False, verbose_name='删除标记')

    class Meta:
        """说明是一个抽象基类"""
        abstract = True

class GisBaseModel(gis_models.Model):
    """模型抽象基类"""
    create_time = models.DateTimeField(auto_now_add=True, null=True, verbose_name='创建时间')
    update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    is_delete = models.BooleanField(default=False, verbose_name='删除标记')
    firm = models.ForeignKey(Firm, null=True, blank=True, on_delete=models.CASCADE, verbose_name='所属企业')
    
    objects = models.manager.Manager()
    request_objects = RequestQuerySet.as_manager()

    class Meta:
        """说明是一个抽象基类"""
        abstract = True

class GisBaseModelNoFirm(gis_models.Model):
    """模型抽象基类"""
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    is_delete = models.BooleanField(default=False, verbose_name='删除标记')

    class Meta:
        """说明是一个抽象基类"""
        abstract = True

class BaseForeignKey(gis_models.ForeignKey):
    def formfield(self, *, using=None, **kwargs):
        if isinstance(self.remote_field.model, str):
            raise ValueError("Cannot create form field for %r yet, because "
                             "its related model %r has not been loaded yet" %
                             (self.name, self.remote_field.model))
        if hasattr(self.remote_field.model, 'request_objects') and getattr(self, 'request', None) is not None:
            queryset = self.remote_field.model.request_objects.using(using).of(self.request)
        else:
            queryset = self.remote_field.model._default_manager.using(using)    
        return super().formfield(**{
            'form_class': forms.ModelChoiceField,
            'queryset': queryset,
            'to_field_name': self.remote_field.field_name,
            **kwargs,
            'blank': self.blank,
        })

class BaseManyToManyField(gis_models.ManyToManyField):
    def formfield(self, *, using=None, **kwargs):
        if hasattr(self.remote_field.model, 'request_objects') and getattr(self, 'request', None) is not None:
            queryset = self.remote_field.model.request_objects.using(using).of(self.request)
        else:
            queryset = self.remote_field.model._default_manager.using(using)    
        defaults = {
            'form_class': forms.ModelMultipleChoiceField,
            'queryset': queryset,
            **kwargs,
        }
        # If initial is passed in, it's a list of related objects, but the
        # MultipleChoiceField takes a list of IDs.
        if defaults.get('initial') is not None:
            initial = defaults['initial']
            if callable(initial):
                initial = initial()
            defaults['initial'] = [i.pk for i in initial]
        return super().formfield(**defaults)

class CronTextField(gis_models.TextField):
    def formfield(self, **kwargs):
        # Passing max_length to forms.CharField means that the value's length
        # will be validated twice. This is considered acceptable since we want
        # the value in the form field (to pass into widget for example).
        kwargs['disabled'] = 'disabled'
        return super().formfield(**{
            'max_length': self.max_length,
            **({} if self.choices is not None else {'widget': forms.Textarea}),
            **kwargs,
        })